#include "animation_set.hpp"
#include "animation_view.hpp"
#include <iostream>
#include <stdexcept>
#include <algorithm>

#include "debug.hpp"
#include "default_image.hpp"

AnimationView::AnimationView():m_width(1024), m_height(768), m_time_from_start(0.f)
{
}

AnimationView::~AnimationView()
{
}

void AnimationView::Initialize(int argc, const char** argv)
{
	if (argc <= 1)
	{
		fire_exception("%s", "no input file");
	}
	const char* file_name = argv[1];
	Initialize(file_name);
}
void AnimationView::Initialize(const char* file_name)
{
	pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_file(file_name);

	if (!result)
	{
		std::stringstream ss;
		ss << "XML [" << file_name << "] parsed with errors" << "\n";
		ss << "Error description: " << result.description() << "\n";
		ss << "Error offset: " << result.offset;
		fire_exception("%s", ss.str().c_str());
	}
	m_anim_dir_path = ExtractAnimDirPath(file_name);
	Initialize(doc);
}

void AnimationView::Initialize(const pugi::xml_document& document)
{
	Clear();
	pugi::xml_node animation = document.child("animation_set");
	m_animation_set.Initialize(animation, m_anim_dir_path);
	if (!m_animation_set.GetImage())
	{
		// установим картинку поумолчанию, что бы видеть что делает эта анимация
		ImagePtr image;
		image.reset(new sf::Image());
		size_t size = g_default_image.width * g_default_image.height * g_default_image.bytes_per_pixel;
		const unsigned char* data = (const unsigned char*)g_default_image.pixel_data;
		if (!image->LoadFromPixels(g_default_image.width, g_default_image.height, data))
		{
			fire_exception("can't load default image file", "");
		}
		m_animation_set.SetImage(image);
	}
}

std::string AnimationView::ExtractAnimDirPath(const char* file_name)
{
	std::string path = file_name;
	std::replace(path.begin(), path.end(), '\\', '/');
	std::string::size_type index = path.find_last_of('/');
	std::string dir_path = path.substr(0, index);
	std::string anim_dir_path = dir_path + "/";
	return anim_dir_path;
}

void AnimationView::Update(float dt)
{
	m_animation_set.Update(dt);
}

void AnimationView::Render(sf::RenderWindow& window) const
{
	m_animation_set.Render(window);
}

void AnimationView::Clear()
{
	m_animation_set.Clear();
}
